//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   testBuiltInCrossSections.cc
 * \author Jeremy Roberts
 * \date   Jul 24, 2011
 * \brief  
 * \note   Copyright (C) 2011 Jeremy Roberts. 
 */
//---------------------------------------------------------------------------//
// $Rev::                                               $:Rev of last commit
// $Author::                                            $:Author of last commit
// $Date::                                              $:Date of last commit
//---------------------------------------------------------------------------//

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <cmath>

#include "test/Testing.hh"

#include "material/BuiltInCrossSections.hh"

using namespace std;
using namespace slabtran;
using namespace util;

//-----------------------------------------------------------------------------
// test data - t prefix avoids possible ambiguity with built in data
//
// xs1g1m
const double t_xs1g1m_sigma_s[] =
{ 0.99, 0.20 };
//
// xs1g2m
const double t_xs1g2m_sigma[] =
{ 1.0, 1.0 };
const double t_xs1g2m_sigma_a[] =
{ 0.5, 0.5 };
const double t_xs1g2m_sigma_f[] =
{ 0.0, 0.25 };
const double t_xs1g2m_nu[] =
{ 0.0, 2.4 };
const double t_xs1g2m_chi[] =
{ 0.0, 1.0 };
const double t_xs1g2m_sigma_s[] =
{ 0.5, 0.5 };
//
// xs2g4m
const double t_xs2g4m_sigma[] =
{ 0.18900, 1.46330, 0.22630, 1.01190,
  0.22520, 0.99150, 0.21730, 1.06060 };
//
// xs6g1m
const double t_xs6g1m_sigma_s[] =
{ 0.11000, 0.01100, 0.12000, 0.01200,
  0.21000, 0.02100, 0.22000, 0.02200, 0.23000, 0.02300,
  0.31000, 0.03100, 0.32000, 0.03200, 0.33000, 0.03300, 0.34000, 0.03400,
                    0.42000, 0.04200, 0.43000, 0.04300, 0.44000, 0.04400, 0.45000, 0.04500,
                                      0.53000, 0.05300, 0.54000, 0.05400, 0.55000, 0.05500, 0.56000, 0.05600,
                                                        0.64000, 0.06400, 0.65000, 0.06500, 0.66000, 0.06600 };

// forward declare tests
int testXS1G1M();
int testXS1G2M();
int testXS2G4M();
int testXS6G1M();

int main(int argc, char *argv[])
{
  Require(argc==2);
  int test = atoi(argv[1]);
  cout << " ------ testBuiltInCrossSections ------ " << endl;
  int test_value = 0;
  int number_of_tests = 5;
  if (test == 1 || test == number_of_tests)
    test_value += testXS1G1M();
  if (test == 1 || test == number_of_tests)
    test_value += testXS1G2M();
  if (test == 3 || test == number_of_tests)
    test_value += testXS2G4M();
  if (test == 4 || test == number_of_tests)
    test_value += testXS6G1M();
  if (test > number_of_tests || test < 1) cout << " test " << test
      << " not available. " << endl;
  if (test_value)
    cout << " failed with value = " << test_value << endl;
  else
    cout << " passed." << endl;
  return test_value;
}

int testXS1G1M()
{
  BuiltInCrossSections xs(BuiltInCrossSections::XS1G1M);
  BuiltInCrossSections::SP_materials mat = xs.build();
  // print material xs data
  mat->print();
  // test s(0->0,l=0)
  TEST( (mat->get(0)).sigma_s(0,0,0) == t_xs1g1m_sigma_s[0]);
  // test s(0->0,l=1)
  TEST( (mat->get(0)).sigma_s(0,0,1) == t_xs1g1m_sigma_s[1]);
  return 0;
}

int testXS1G2M()
{
  BuiltInCrossSections xs(BuiltInCrossSections::XS1G2M);
  BuiltInCrossSections::SP_materials mat = xs.build();
  // test sigma_total for both materials
  TEST((mat->get(0)).sigma(0) == t_xs1g2m_sigma[0]);
  TEST((mat->get(1)).sigma(0) == t_xs1g2m_sigma[1]);
  // test sigma_a for both materials
  TEST((mat->get(0)).sigma_a(0) == t_xs1g2m_sigma_a[0]);
  TEST((mat->get(1)).sigma_a(0) == t_xs1g2m_sigma_a[1]);
  // test sigma_f for both materials
  TEST((mat->get(0)).sigma_f(0) == t_xs1g2m_sigma_f[0]);
  TEST((mat->get(1)).sigma_f(0) == t_xs1g2m_sigma_f[1]);
  // test nu for both materials
  TEST((mat->get(0)).nu(0) == t_xs1g2m_nu[0]);
  TEST((mat->get(1)).nu(0) == t_xs1g2m_nu[1]);
  // test chi for both materials
  TEST((mat->get(0)).chi(0) == t_xs1g2m_chi[0]);
  TEST((mat->get(1)).chi(0) == t_xs1g2m_chi[1]);
  return 0;
}

int testXS2G4M()
{
  BuiltInCrossSections xs(BuiltInCrossSections::XS2G4M);
  BuiltInCrossSections::SP_materials mat = xs.build();
  // print material xs data
  mat->print();
  // test sigma for all four materials and two groups
  TEST((mat->get(0)).sigma(0) == t_xs2g4m_sigma[0]);
  TEST((mat->get(0)).sigma(1) == t_xs2g4m_sigma[1]);
  TEST((mat->get(1)).sigma(0) == t_xs2g4m_sigma[2]);
  TEST((mat->get(1)).sigma(1) == t_xs2g4m_sigma[3]);
  TEST((mat->get(2)).sigma(0) == t_xs2g4m_sigma[4]);
  TEST((mat->get(2)).sigma(1) == t_xs2g4m_sigma[5]);
  TEST((mat->get(3)).sigma(0) == t_xs2g4m_sigma[6]);
  TEST((mat->get(3)).sigma(1) == t_xs2g4m_sigma[7]);
  return 0;
}

int testXS6G1M()
{
  BuiltInCrossSections xs(BuiltInCrossSections::XS6G1M);
  BuiltInCrossSections::SP_materials mat = xs.build();
  // print material xs data
  mat->print();
  // test scattering 2 group, first order scattering matrix
//  const double xs6g1m_sigma_s[] = // matrix indices (group indices)
//  { 0.11000, 0.01100, 0.12000, 0.01200, // 0,3 (0,1)
//    0.21000, 0.02100, 0.22000, 0.02200, 0.23000, 0.02300, // 4,9 (0,2)
//    0.31000, 0.03100, 0.32000, 0.03200, 0.33000, 0.03300, 0.34000, 0.03400, // 10,17 (0,3)
//                      0.42000, 0.04200, 0.43000, 0.04300, 0.44000, 0.04400, 0.45000, 0.04500, // 18,25 (1,4)
//                                        0.53000, 0.05300, 0.54000, 0.05400, 0.55000, 0.05500, 0.56000, 0.05600, // 26,33 (2,5)
//                                                          0.64000, 0.06400, 0.65000, 0.06500, 0.66000, 0.06600 }; // 34,39 (3,5)
  // g=0 <-- g_prime
  TEST((mat->get(0)).group_lower_bound(0) == 0);
  TEST((mat->get(0)).group_upper_bound(0) == 1);
  TEST((mat->get(0)).sigma_s(0,0,0) == t_xs6g1m_sigma_s[0]);
  TEST((mat->get(0)).sigma_s(0,0,1) == t_xs6g1m_sigma_s[1]);
  TEST((mat->get(0)).sigma_s(0,1,0) == t_xs6g1m_sigma_s[2]);
  TEST((mat->get(0)).sigma_s(0,1,1) == t_xs6g1m_sigma_s[3]);
  // g=1 <-- g_prime
  TEST((mat->get(0)).group_lower_bound(1) == 0);
  TEST((mat->get(0)).group_upper_bound(1) == 2);
  TEST((mat->get(0)).sigma_s(1,0,0) == t_xs6g1m_sigma_s[4]);
  TEST((mat->get(0)).sigma_s(1,0,1) == t_xs6g1m_sigma_s[5]);
  TEST((mat->get(0)).sigma_s(1,1,0) == t_xs6g1m_sigma_s[6]);
  TEST((mat->get(0)).sigma_s(1,1,1) == t_xs6g1m_sigma_s[7]);
  TEST((mat->get(0)).sigma_s(1,2,0) == t_xs6g1m_sigma_s[8]);
  TEST((mat->get(0)).sigma_s(1,2,1) == t_xs6g1m_sigma_s[9]);
  // g=2 <-- g_prime
  TEST((mat->get(0)).group_lower_bound(2) == 0);
  TEST((mat->get(0)).group_upper_bound(2) == 3);
  TEST((mat->get(0)).sigma_s(2,0,0) == t_xs6g1m_sigma_s[10]);
  TEST((mat->get(0)).sigma_s(2,0,1) == t_xs6g1m_sigma_s[11]);
  TEST((mat->get(0)).sigma_s(2,1,0) == t_xs6g1m_sigma_s[12]);
  TEST((mat->get(0)).sigma_s(2,1,1) == t_xs6g1m_sigma_s[13]);
  TEST((mat->get(0)).sigma_s(2,2,0) == t_xs6g1m_sigma_s[14]);
  TEST((mat->get(0)).sigma_s(2,2,1) == t_xs6g1m_sigma_s[15]);
  TEST((mat->get(0)).sigma_s(2,3,0) == t_xs6g1m_sigma_s[16]);
  TEST((mat->get(0)).sigma_s(2,3,1) == t_xs6g1m_sigma_s[17]);
  // g=3 <-- g_prime
  TEST((mat->get(0)).group_lower_bound(3) == 1);
  TEST((mat->get(0)).group_upper_bound(3) == 4);
  TEST((mat->get(0)).sigma_s(3,1,0) == t_xs6g1m_sigma_s[18]);
  TEST((mat->get(0)).sigma_s(3,1,1) == t_xs6g1m_sigma_s[19]);
  TEST((mat->get(0)).sigma_s(3,2,0) == t_xs6g1m_sigma_s[20]);
  TEST((mat->get(0)).sigma_s(3,2,1) == t_xs6g1m_sigma_s[21]);
  TEST((mat->get(0)).sigma_s(3,3,0) == t_xs6g1m_sigma_s[22]);
  TEST((mat->get(0)).sigma_s(3,3,1) == t_xs6g1m_sigma_s[23]);
  TEST((mat->get(0)).sigma_s(3,4,0) == t_xs6g1m_sigma_s[24]);
  TEST((mat->get(0)).sigma_s(3,4,1) == t_xs6g1m_sigma_s[25]);
  // g=4 <-- g_prime
  TEST((mat->get(0)).group_lower_bound(4) == 2);
  TEST((mat->get(0)).group_upper_bound(4) == 5);
  TEST((mat->get(0)).sigma_s(4,2,0) == t_xs6g1m_sigma_s[26]);
  TEST((mat->get(0)).sigma_s(4,2,1) == t_xs6g1m_sigma_s[27]);
  TEST((mat->get(0)).sigma_s(4,3,0) == t_xs6g1m_sigma_s[28]);
  TEST((mat->get(0)).sigma_s(4,3,1) == t_xs6g1m_sigma_s[29]);
  TEST((mat->get(0)).sigma_s(4,4,0) == t_xs6g1m_sigma_s[30]);
  TEST((mat->get(0)).sigma_s(4,4,1) == t_xs6g1m_sigma_s[31]);
  TEST((mat->get(0)).sigma_s(4,5,0) == t_xs6g1m_sigma_s[32]);
  TEST((mat->get(0)).sigma_s(4,5,1) == t_xs6g1m_sigma_s[33]);
  // g=5 <-- g_prime
  TEST((mat->get(0)).group_lower_bound(5) == 3);
  TEST((mat->get(0)).group_upper_bound(5) == 5);
  TEST((mat->get(0)).sigma_s(5,3,0) == t_xs6g1m_sigma_s[34]);
  TEST((mat->get(0)).sigma_s(5,3,1) == t_xs6g1m_sigma_s[35]);
  TEST((mat->get(0)).sigma_s(5,4,0) == t_xs6g1m_sigma_s[36]);
  TEST((mat->get(0)).sigma_s(5,4,1) == t_xs6g1m_sigma_s[37]);
  TEST((mat->get(0)).sigma_s(5,5,0) == t_xs6g1m_sigma_s[38]);
  TEST((mat->get(0)).sigma_s(5,5,1) == t_xs6g1m_sigma_s[39]);
  return 0;
}

//---------------------------------------------------------------------------//
//              end of testBuiltInCrossSections.cc
//---------------------------------------------------------------------------//
